From 6f45cb618231c98ccf35358decc9c388c453941a Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Fri, 16 Jun 2017 14:57:27 +1200 Subject: [PATCH] Support having a generic writer instead of a termcolor StandardStream This is requied by the RLS (and presumably any other client who wants to use Cargo as a lib and redirect output) --- src/cargo/core/shell.rs | 109 ++++++++++++++++++------- src/cargo/lib.rs | 1 - src/cargo/ops/cargo_new.rs | 1 - src/cargo/ops/cargo_rustc/job_queue.rs | 2 +- src/cargo/ops/registry.rs | 1 - 5 files changed, 79 insertions(+), 35 deletions(-) diff --git a/src/cargo/core/shell.rs b/src/cargo/core/shell.rs index 1dfeb375c..d6edde59c 100644 --- a/src/cargo/core/shell.rs +++ b/src/cargo/core/shell.rs @@ -15,9 +15,13 @@ pub enum Verbosity { } pub struct Shell { - err: StandardStream, + err: ShellOut, verbosity: Verbosity, - choice: ColorChoice, +} + +enum ShellOut { + Write(Box), + Stream(StandardStream, ColorChoice), } #[derive(PartialEq, Clone, Copy)] @@ -30,9 +34,18 @@ pub enum ColorChoice { impl Shell { pub fn new() -> Shell { Shell { - err: StandardStream::stderr(ColorChoice::CargoAuto.to_termcolor_color_choice()), + err: ShellOut::Stream( + StandardStream::stderr(ColorChoice::CargoAuto.to_termcolor_color_choice()), + ColorChoice::CargoAuto, + ), + verbosity: Verbosity::Verbose, + } + } + + pub fn from_write(out: Box) -> Shell { + Shell { + err: ShellOut::Write(out), verbosity: Verbosity::Verbose, - choice: ColorChoice::CargoAuto, } } @@ -44,24 +57,13 @@ impl Shell { match self.verbosity { Verbosity::Quiet => Ok(()), _ => { - self.err.reset()?; - self.err.set_color(ColorSpec::new() - .set_bold(true) - .set_fg(Some(color)))?; - if justified { - write!(self.err, "{:>12}", status)?; - } else { - write!(self.err, "{}", status)?; - } - self.err.reset()?; - write!(self.err, " {}\n", message)?; - Ok(()) + self.err.print(status, message, color, justified) } } } - pub fn err(&mut self) -> &mut StandardStream { - &mut self.err + pub fn err(&mut self) -> &mut Write { + self.err.as_write() } pub fn status(&mut self, status: T, message: U) -> CargoResult<()> @@ -117,23 +119,68 @@ impl Shell { } pub fn set_color_choice(&mut self, color: Option<&str>) -> CargoResult<()> { - let cfg = match color { - Some("always") => ColorChoice::Always, - Some("never") => ColorChoice::Never, + if let ShellOut::Stream(ref mut err, ref mut cc) = self.err { + let cfg = match color { + Some("always") => ColorChoice::Always, + Some("never") => ColorChoice::Never, + + Some("auto") | + None => ColorChoice::CargoAuto, + + Some(arg) => bail!("argument for --color must be auto, always, or \ + never, but found `{}`", arg), + }; + *cc = cfg; + *err = StandardStream::stderr(cfg.to_termcolor_color_choice()); + } + Ok(()) + } - Some("auto") | - None => ColorChoice::CargoAuto, + pub fn color_choice(&self) -> ColorChoice { + match self.err { + ShellOut::Stream(_, cc) => cc, + ShellOut::Write(_) => ColorChoice::Never, + } + } +} - Some(arg) => bail!("argument for --color must be auto, always, or \ - never, but found `{}`", arg), - }; - self.choice = cfg; - self.err = StandardStream::stderr(cfg.to_termcolor_color_choice()); - return Ok(()); +impl ShellOut { + fn print(&mut self, + status: &fmt::Display, + message: &fmt::Display, + color: Color, + justified: bool) -> CargoResult<()> { + match *self { + ShellOut::Stream(ref mut err, _) => { + err.reset()?; + err.set_color(ColorSpec::new() + .set_bold(true) + .set_fg(Some(color)))?; + if justified { + write!(err, "{:>12}", status)?; + } else { + write!(err, "{}", status)?; + } + err.reset()?; + write!(err, " {}\n", message)?; + } + ShellOut::Write(ref mut w) => { + if justified { + write!(w, "{:>12}", status)?; + } else { + write!(w, "{}", status)?; + } + write!(w, " {}\n", message)?; + } + } + Ok(()) } - pub fn color_choice(&self) -> ColorChoice { - self.choice + fn as_write(&mut self) -> &mut Write { + match *self { + ShellOut::Stream(ref mut err, _) => err, + ShellOut::Write(ref mut w) => w, + } } } diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 3f03697d4..5a1c3de14 100755 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -33,7 +33,6 @@ extern crate termcolor; extern crate toml; extern crate url; -use std::io::Write; use std::fmt; use std::error::Error; diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index fdff07ee3..31c308bb9 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -1,7 +1,6 @@ use std::collections::BTreeMap; use std::env; use std::fs; -use std::io::Write; use std::path::Path; use serde::{Deserialize, Deserializer}; diff --git a/src/cargo/ops/cargo_rustc/job_queue.rs b/src/cargo/ops/cargo_rustc/job_queue.rs index aec3e3c85..1934e2c8b 100644 --- a/src/cargo/ops/cargo_rustc/job_queue.rs +++ b/src/cargo/ops/cargo_rustc/job_queue.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use std::collections::hash_map::HashMap; use std::fmt; -use std::io::{self, Write}; +use std::io; use std::mem; use std::sync::mpsc::{channel, Sender, Receiver}; diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 01a5e0710..35ec30257 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -1,6 +1,5 @@ use std::env; use std::fs::{self, File}; -use std::io::Write; use std::iter::repeat; use std::time::Duration; -- 2.30.2